package com.smart.manager.system.repository;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Opt;
import com.smart.common.entities.core.Page;
import com.smart.common.entities.option.SelectOption;
import com.smart.manager.system.entities.body.RSystemScheduleApp;
import com.smart.manager.system.entities.models.SystemScheduleApp;
import com.smart.manager.system.entities.models.query.QSystemScheduleApp;
import com.smart.manager.system.handler.TaskAppScanner;
import io.ebean.DB;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author Administrator
 */
@Service
@Log4j2
@RequiredArgsConstructor
public class ScheduleAppRepository {


    public Page<SystemScheduleApp> pageList(RSystemScheduleApp.SearchBody search) {
        QSystemScheduleApp query = new QSystemScheduleApp();
        Opt.ofBlankAble(search.getName()).ifPresent(x -> query.name.contains(x));
        Opt.ofBlankAble(search.getBeanName()).ifPresent(x -> query.beanName.contains(x));
        Opt.ofBlankAble(search.getMethodName()).ifPresent(x -> query.methodName.contains(x));
        Opt.ofBlankAble(search.getRemark()).ifPresent(x -> query.remark.contains(x));
        Opt.ofNullable(search.getParameterType()).ifPresent(x -> query.parameterType.eq(x));
        query.setFirstRow(search.firstRow()).setMaxRows(search.maxRows()).order().id.desc();
        return new Page<SystemScheduleApp>().load(query.findPagedList());
    }


    /**
     * 扫描当前系统所有任务程序
     */

    @Transactional(rollbackFor = Exception.class)
    public void scan() {
        //扫描当前程序包含的计划任务应用列表
        ArrayList<SystemScheduleApp> newList = TaskAppScanner.getAllSystemScheduleApp();
        List<SystemScheduleApp> oldList = new QSystemScheduleApp().findList();
        //新旧同时为空 终止程序
        if (CollUtil.isEmpty(oldList) && CollUtil.isEmpty(newList)) {
            return;
        }
        //旧非空 新空 删除所有任务
        if (CollUtil.isNotEmpty(oldList) && CollUtil.isEmpty(newList)) {
            DB.deleteAll(oldList);
            return;
        }
        //旧空 新非空 注册所有程序
        if (CollUtil.isEmpty(oldList) && CollUtil.isNotEmpty(newList)) {
            DB.saveAll(newList);
            return;
        }
        //对比 检查需要删除可修改的数据
        Set<String> oldTokes = oldList.stream().map(SystemScheduleApp::getToken).collect(Collectors.toSet());
        Set<String> newTokens = newList.stream().map(SystemScheduleApp::getToken).collect(Collectors.toSet());
        for (SystemScheduleApp item : newList) {
            //老的不包含新的 将本条数据加入插入
            if (!oldTokes.contains(item.getToken())) {
                log.error("发现新的定时任务 {}" ,item);
                item.insert();
            }
        }
        for (SystemScheduleApp scheduleApp : oldList) {
            if (!newTokens.contains(scheduleApp.getToken())) {
                scheduleApp.delete();
            }
        }
    }

    /**
     * 获取定时任务数据字典
     *
     * @return {@link List}<{@link SelectOption}>
     */
    public List<SelectOption> getOptions() {
        return new QSystemScheduleApp().findStream()
                .map(x -> new SelectOption().setLabel(x.getName()).setValue(x.getId().toString()).setDisabled(false))
                .collect(Collectors.toList());
    }
}
